package com.ashen.boot.admin.project.system.datapermission.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Sets;
import com.ashen.boot.admin.domain.service.impl.SuperBaseServiceImpl;
import com.ashen.boot.admin.project.system.datapermission.mapper.IUserDataPermissionMapper;
import com.ashen.boot.admin.project.system.datapermission.model.dto.UserDataPermissionDTO;
import com.ashen.boot.admin.project.system.datapermission.model.entity.UserDataPermissionEntity;
import com.ashen.boot.admin.project.system.datapermission.model.query.UserDataPermissionParams;
import com.ashen.boot.admin.project.system.datapermission.service.IUserDataPermissionService;
import com.ashen.boot.admin.project.system.user.service.IUserDataTypeService;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import javax.annotation.Nonnull;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户数据权限 服务实现类
 * </p>
 *
 * @author gao
 * @since 2021-11-08
 */
@Service
@RequiredArgsConstructor
public class UserDataPermissionServiceImpl extends SuperBaseServiceImpl<Long, UserDataPermissionParams, UserDataPermissionDTO, UserDataPermissionEntity, IUserDataPermissionMapper> implements IUserDataPermissionService {

    @Getter
    private final IUserDataTypeService userDataTypeService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateUserDataPermission(@Nonnull Long userId, @Nonnull Long dataPermissionId, @Nonnull int isall, Collection<String> permissionIds) {
        Assert.notNull(userId, "用户id为空");
        LambdaQueryWrapper<UserDataPermissionEntity> queryWrapper = Wrappers.lambdaQuery(UserDataPermissionEntity.class).eq(UserDataPermissionEntity::getUserId, userId).in(UserDataPermissionEntity::getDataPermissionId, dataPermissionId);
        userDataTypeService.updateUserDataType(userId,dataPermissionId,isall);

        // 用户没有选择数据权限
        if (CollectionUtils.isEmpty(permissionIds) || isall==1) {
            super.remove(queryWrapper);
            return true;
        }
        // 获取旧数据
        List<UserDataPermissionEntity> entities = super.list(queryWrapper);
        // 旧数据为空说明是新增用户新增角色
        if (CollectionUtils.isEmpty(entities)) {
            saveBatch(userId, dataPermissionId, permissionIds);
            return true;
        }
        // 新旧更替
        Set<String> oldPermissionIds = entities.parallelStream().map(UserDataPermissionEntity::getPermissionVal).collect(Collectors.toSet());

        Set<String> newPermissionIds = Sets.newHashSet(permissionIds);

        //新数据-旧数据=新增数据  新增
        newPermissionIds.removeAll(oldPermissionIds);
        if (!CollectionUtils.isEmpty(newPermissionIds)) {
            saveBatch(userId,dataPermissionId, newPermissionIds);
        }
        // 旧数据-新数据=过期数据 删除

        oldPermissionIds.removeAll(permissionIds);
        if (!CollectionUtils.isEmpty(oldPermissionIds)) {
            queryWrapper = Wrappers.lambdaQuery(UserDataPermissionEntity.class).eq(UserDataPermissionEntity::getUserId, userId).
                    eq(UserDataPermissionEntity::getDataPermissionId,dataPermissionId).in(UserDataPermissionEntity::getPermissionVal, oldPermissionIds);
            remove(queryWrapper);
        }
        return true;
    }

    private void saveBatch(@Nonnull Long userId, @Nonnull Long dataPermissionId, @Nonnull Collection<String> permissionIds) {
        Assert.notNull(userId, "用户id为空");
        Assert.notNull(dataPermissionId, "权限类型id为空");
        Assert.notEmpty(permissionIds, "权限id为空");
        List<UserDataPermissionEntity> entities = new ArrayList<>(permissionIds.size());
        for (String permissionId : permissionIds) {
            UserDataPermissionEntity entity = new UserDataPermissionEntity();
            entity.setUserId(userId);
            entity.setDataPermissionId(dataPermissionId);
            entity.setPermissionVal(permissionId);
            entities.add(entity);
        }
        saveBatch(entities);
    }
}
